import 'package:sow_app_core/sow_app_core.dart';
import 'package:sow_app_core/src/usecase/token_usecase.dart';

import 'captcha_image_usecase.dart';
import 'usecase.dart';

class GetUserUseCase extends UseCase<Future<User>, NoParams> {
  final UserRepository _repository;

  GetUserUseCase(this._repository);
  @override
  Future<User> call(NoParams params) => _repository.info();
}

class LoginUseCase extends UseCase<Future<String>, LoginParam> {
  final UserRepository _userRepository;

  LoginUseCase(this._userRepository);

  @override
  Future<String> call(LoginParam params) async {
    String token =
        await _userRepository.login(params.username, params.password);
    return token;
  }
}

class LoginParam {
  final String username;
  final String password;
  final String captcha;
  final String uuid;

  LoginParam(this.username, this.password, this.captcha, this.uuid);
}

class RegisterUseCase extends UseCase<Future<String>, RegisterParam> {
  final UserRepository _userRepository;

  RegisterUseCase(this._userRepository);
  @override
  Future<String> call(RegisterParam params) async {
    return await _userRepository.register(
        params.username, params.password, int.parse(params.velCode));
  }
}

class RegisterParam {
  final String username;
  final String password;
  final String velCode;

  RegisterParam(this.username, this.password, this.velCode);
}

class InitUserInfoUseCase extends UseCase<void, NoParams> {
  final InfoPresenter _presenter;
  final UserRepository _userRepository;

  InitUserInfoUseCase(this._presenter, this._userRepository);

  @override
  Future<void> call(NoParams params) async {
    try {
      final user = (await GetUserUseCase(_userRepository)(NoParams()));
      _presenter.user = user;
    } on UserNotfoundException {
      _presenter.user = User.empty;
    } on ServerException catch (e) {
      _presenter.user = User.empty;
      _presenter.onError(e);
    } finally {
      _presenter.onComplete();
    }
  }
}

class UserRegisterUseCase extends UseCase<void, NoParams> {
  final RegisterPresenter _presenter;
  final UserRepository _userRepository;
  final TokenRepository _tokenRepository;
  final RestClient _client;

  UserRegisterUseCase(this._presenter, this._userRepository,
      this._tokenRepository, this._client);
  @override
  void call(NoParams params) async {
    try {
      final String token = await RegisterUseCase(_userRepository)(RegisterParam(
          _presenter.username!, _presenter.password!, _presenter.captchaCode!));
      await SetTokenUseCase(_tokenRepository, _client)(token);
      _presenter.onComplete();
      _presenter.onPop();
    } on ServerException catch (e) {
      _presenter.onError(e);
    }
  }
}

class RegisterGetCaptchaUseCase extends UseCase<void, NoParams> {
  final RegisterPresenter _presenter;
  final CaptchaImageRepository _captchaImageRepository;

  RegisterGetCaptchaUseCase(this._presenter, this._captchaImageRepository);
  @override
  void call(NoParams params) async {
    _presenter.captcha =
        (await GetCaptchaImageUseCase(_captchaImageRepository)(NoParams()))
            .image;
    _presenter.onComplete();
  }
}

class LoginClearUserUseCase extends UseCase<void, NoParams> {
  final LoginPresenter presenter;
  final TokenRepository _tokenRepository;
  final RestClient _client;

  LoginClearUserUseCase(this.presenter, this._tokenRepository, this._client);
  @override
  void call(NoParams params) async {
    await SetTokenUseCase(_tokenRepository, _client)("");
    presenter.onLogout();
    presenter.onComplete();
  }
}
